package com.sunclouder.cactus.util;

import java.util.function.Supplier;
import javax.validation.constraints.NotNull;

import cn.hutool.json.JSONUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.event.Level;

public class LogUtils {
    private static final Integer LOG_MAX_PRINT_LENGTH = 1000;

    private LogUtils() {
    }

    public static void invokingInfoLog(Logger logger, String methodName, String... arg) {
        logger.info("start calling a dubbo interface, name is {}, parameter is {}", methodName, String.join(",", arg));
    }

    public static void invokedInfoLog(Logger logger, String methodName, Object result) {
        logger.info("end call a dubbo interface, name is {}, result is {}", methodName, JSONUtil.toJsonStr(result));
    }

    public static <T> T invokeInfoLog(Supplier<T> supplier, Logger logger, String methodName, String... param) {
        invokingInfoLog(logger, methodName, param);
        T result = supplier.get();
        invokedInfoLog(logger, methodName, result);
        return result;
    }

    public static String newLine() {
        return System.lineSeparator();
    }

    public static String getLogException(Throwable e) {
        if (e == null) {
            return null;
        } else {
            StringBuilder stringBuilder = new StringBuilder();
            String errorMessage = e.getMessage();
            if (StringUtils.isNotBlank(errorMessage)) {
                stringBuilder.append(System.lineSeparator()).append("error message:").append(errorMessage);
            }

            if (StringUtils.isNotBlank(ExceptionUtils.getStackTrace(e))) {
                stringBuilder.append(System.lineSeparator()).append(ExceptionUtils.getStackTrace(e));
            }

            return stringBuilder.toString();
        }
    }

    public static String getLogException(Throwable e, Level level, Logger log) {
        boolean logEnable = level == Level.TRACE && log.isTraceEnabled() || level == Level.DEBUG && log.isDebugEnabled() || level == Level.INFO && log.isInfoEnabled() || level == Level.WARN && log.isInfoEnabled() || level == Level.ERROR && log.isErrorEnabled();
        if (!logEnable) {
            return null;
        } else if (e == null) {
            return null;
        } else {
            StringBuilder stringBuilder = new StringBuilder();
            String errorMessage = e.getMessage();
            if (StringUtils.isNotBlank(errorMessage)) {
                stringBuilder.append(System.lineSeparator()).append("error message:").append(errorMessage);
            }

            if (StringUtils.isNotBlank(ExceptionUtils.getStackTrace(e))) {
                stringBuilder.append(System.lineSeparator()).append(ExceptionUtils.getStackTrace(e));
            }

            return stringBuilder.toString();
        }
    }

    public void trace(Logger log, String format, Object... objects) {
        log.trace(format, objects);
    }

    public static String log(@NotNull Object object) {
        return StringUtils.substring(object.toString(), 0, LOG_MAX_PRINT_LENGTH);
    }
}

